package 多线程.力扣1114_按序打印;

public class OrderedExecutionWaitNotify {

    // 状态变量，1=T1执行, 2=T2执行, 3=T3执行
    private int turn = 1;

    public void printOne() {
        synchronized (this) {
            // 使用while循环防止“虚假唤醒”
            while (turn != 1) {
                try {
                    this.wait(); // 不是自己的回合，释放锁并等待
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
            // 轮到自己了
            System.out.println(Thread.currentThread().getName() + ": one");
            // 更新状态，轮到下一个线程
            turn = 2;
            // 唤醒所有在this上等待的线程
            this.notifyAll();
        }
    }

    public void printTwo() {
        synchronized (this) {
            while (turn != 2) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
            System.out.println(Thread.currentThread().getName() + ": two");
            turn = 3;
            this.notifyAll();
        }
    }

    public void printThree() {
        synchronized (this) {
            while (turn != 3) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
            System.out.println(Thread.currentThread().getName() + ": three");
            // (可选) 任务完成，可以重置状态或结束
        }
    }

    public static void main(String[] args) {
        OrderedExecutionWaitNotify orderedExecution = new OrderedExecutionWaitNotify();

        Thread t1 = new Thread(orderedExecution::printOne, "T1");
        Thread t2 = new Thread(orderedExecution::printTwo, "T2");
        Thread t3 = new Thread(orderedExecution::printThree, "T3");
        
        // 启动顺序不重要，同步机制会保证执行顺序
        t2.start();
        t3.start();
        t1.start();
    }
}